package com.heima.user.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.exception.CustomException;
import com.heima.common.redis.CacheService;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.dtos.AttentionDto;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.user.pojos.ApUserFan;
import com.heima.user.mapper.ApUserFanMapper;
import com.heima.user.mapper.ApUserMapper;
import com.heima.user.service.AttentionService;
import com.heima.utils.thread.AppUserThreadLocalUnit;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class AttentionServiceImpl extends ServiceImpl<ApUserFanMapper, ApUserFan> implements AttentionService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private CacheService cacheService;
    @Autowired
    private ApUserMapper apUserMapper;

    /**
     * 关注/取消关注
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult attention(AttentionDto dto) {
        //1、参数校验
        if (dto == null || dto.getOperation() == null || dto.getAuthorId() == null || dto.getArticleId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2、业务处理
        //2.1、获取当前用户id
        Integer userId = AppUserThreadLocalUnit.get();
        if (userId == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        /**
         *      List<Integer> fans = (List<Integer>) redisTemplate.opsForValue().get(dto.getAuthorId().toString());
         */
        // 2.2、取出作者的粉丝列表
        List<Object> fans = cacheService.hValues(dto.getAuthorId().toString());

        /**
         *         List<Integer> idols = (List<Integer>) redisTemplate.opsForValue().get(userId.toString());
          */
        // 2.3、取出用户的关注列表
        List<Object> idols = cacheService.hValues(userId.toString());
        // 2.4、关注
        if (dto.getOperation() == 0) {
            // 作者多了一个粉丝
            if (fans == null) {
                fans = new ArrayList<>();
            }
            //用户添加到作者的粉丝列表
            fans.add(userId);
            // 添加到redis
            handleService(dto.getAuthorId() + "_author", fans);

            /** handleAttention(dto.getAuthorId(), fans, userId, false, dto.getOperation());*/

            // 用户多了一个关注
            if (idols == null) {
                idols = new ArrayList<>();
            }
            //作者添加到用户的关注列表
            idols.add(dto.getAuthorId());
            //添加到redis
            handleService(userId + "_user", fans);

            /**  handleAttention(userId, idols, dto.getAuthorId(), true, dto.getOperation());*/
        }

        // 2.5、取消关注
        if (dto.getOperation() == 1) {
            // 作者少一个粉丝
            fans.remove(userId);
            //重新存入redis
            handleService(dto.getAuthorId() + "_author",fans);
            //handleAttention(dto.getAuthorId(), fans, userId, false, dto.getOperation());
            // 用户少一个关注
            idols.remove(dto.getAuthorId());
            //重新存入redis
            handleService(userId + "_user",idols);
            //  handleAttention(userId, idols, dto.getAuthorId(), true, dto.getOperation());
        }
        //3、保存到数据库
        saveToDb(dto,userId);
        //4、返回响应结果
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 保存到数据库
     * @param dto
     * @param userId 用户id（粉丝id）
     */
    private void saveToDb(AttentionDto dto, Integer userId) {
        //0、查询数据库得出粉丝姓名
        ApUser apUser = apUserMapper.selectById(userId);
        //1、创建数据库保存对象
        ApUserFan apUserFan = ApUserFan.builder()
                .followId(userId)
                .userId(dto.getAuthorId())
                .createdTime(new Date())
                .follow_name(apUser.getName()).build();
        //判断 0：关注即新增    1：取消关注 删除
        if (dto.getOperation().equals(0)) {
            //新增
            save(apUserFan);
        }else
            //删除
            remove(Wrappers.<ApUserFan>lambdaQuery().eq(ApUserFan::getUserId,dto.getAuthorId()).eq(ApUserFan::getFollowId,userId));
    }

    /**
     * 关注逻辑处理 2.0
     * @param id
     * @param list
     */
    private void handleService(String id, List<Object> list) {
        //stream流处理成String的集合
//        List<Object> listStr = list.stream().map(Object::toString).collect(Collectors.toList());
        cacheService.lLeftPushAll1(id, list);
    }

    /**
     * 关注逻辑处理 1.0
     */
   /* private void handleAttention(Integer userId, List<Object> list, Integer authorId, Boolean flag, Integer operation) {
        if (operation == 0) {
            // 代码健壮性
            if (list == null) {
                list = new ArrayList<>();
            }
            if (flag) {
                // 作者id加入该用户关注列表 /
                list.add(authorId);
                //  redisTemplate.opsForValue().set(userId.toString(), list);
                handleService(userId, list);
            } else {
                // 用户id加入作者粉丝列表
                list.add(userId);
                redisTemplate.opsForValue().set(authorId.toString(), list);
            }
        } else {
            if (flag) {
                if (!list.contains(authorId)) {
                    throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST);
                }
                // 该用户关注列表减去作者id
                list.remove(authorId);
                redisTemplate.opsForValue().set(userId.toString(), list);
            } else {
                if (!list.contains(userId)) {
                    throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST);
                }
                // 作者粉丝列表减去用户id
                list.remove(userId);
                redisTemplate.opsForValue().set(authorId.toString(), list);
            }
        }
    }*/

    public static void main(String[] args) {
        ArrayList<Integer> objects = new ArrayList<>();
        objects.add(1);
        System.out.println(objects);
        objects.remove(0);
        System.out.println(objects);
    }
}
